# -*- coding: utf-8 -*-
#!/usr/bin/python

##copyright 2013 Sebastian Stetter
##http://lemonade.sebastianstetter.de

import os,  getpass
from camelot.admin.action import Action
from camelot.admin.action.form_action import  CloseForm
from camelot.core.utils import ugettext_lazy as _
from camelot.core.conf import settings
from camelot.view.art import Icon
from camelot.view.action_steps import PrintHtml,  MessageBox
from camelot.view.action_steps.orm import FlushSession
from PyQt4.QtGui import QDesktopServices, QMessageBox
from PyQt4.QtCore import QUrl
from camelot.view.action_steps import OpenFormView 


from sqlalchemy import orm
from camelot.core.orm import Session

from jinja2 import Environment, FileSystemLoader
from pkg_resources import resource_filename
import lemonade.model 
from lemonade.action_steps import *


class CloseFormAction(Action):
    """this action provides a hook that is called on the model_context's object when it's form is closed (after validation)"""
    verbose_name=_('Close')
    icon = Icon('tango/32x32/actions/system-log-out.png')
    
    def model_run(self, model_context):
        obj = model_context.get_object()
        #see if we can call on_close() on this object
        if hasattr(obj, "on_close") and callable(getattr(obj,"on_close")):
            obj.on_close()    
        yield CloseForm()

#######
class ValidateFormBeforeCloseFormAction( Action ):
    """Validate the form can be closed before calling our CloseFormAction. 
    This way we can make sure the Form can be closed before we execute our on_close() functions. 
    The Form will be validated again by CloseForm, though. 
    This way we will be shure we do not mess up things in on_close()"""
    
    #shortcut = QtGui.QKeySequence.Close
    icon = Icon('tango/16x16/actions/system-log-out.png')
    verbose_name = _('Close')
    tooltip = _('Close')
    
    def gui_run( self, gui_context ):
        gui_context.widget_mapper.submit()
        super( ValidateFormBeforeCloseFormAction, self ).gui_run( gui_context )
        
    def model_run( self, model_context ):
        from PyQt4 import QtGui
        from camelot.view import action_steps
        yield action_steps.UpdateProgress( text = _('Validating Form') )
        validator = model_context.admin.get_validator()
        obj = model_context.get_object()
        admin  = model_context.admin
        if obj == None:
            yield action_steps.CloseView()
        #
        # validate the object, and if the object is valid, simply close
        # the view
        #
        messages = validator.objectValidity( obj )
        valid = ( len( messages ) == 0 )
        if valid:
            ###Form is valid what do we do now?
            yield CloseFormAction()
        else:
            #
            # if the object is not valid, request the user what to do
            #
            message = action_steps.MessageBox( '\n'.join( messages ),
                                               QtGui.QMessageBox.Warning,
                                               #_('Invalid form'),
                                               _('Invalid form on_close'),
                                               QtGui.QMessageBox.Ok | QtGui.QMessageBox.Discard )
            reply = yield message
            if reply == QtGui.QMessageBox.Discard:
                yield action_steps.CloseView()
                if admin.is_persistent( obj ):
                    admin.refresh( obj )
                    yield action_steps.UpdateObject( obj )
                else:
                    yield action_steps.DeleteObject( obj )
                    admin.expunge( obj )

class SendStandardEmail(Action):
    verbose_name=_("Send standard email")
    icon = Icon('tango/32x32/actions/mail-message-new.png')
    tooltip = _('Send predefined email to Customer and create a new contact entry')
    
    
    def model_run(self,  model_context):
        obj = model_context.get_object()
        if type(obj) == lemonade.model.Opportunity:
            #action is called in Opportunity context
            opp = obj
            customer = opp.customer
        elif type(obj) == lemonade.model.Contact:
            #action is called in Contact context
            cont = obj
            customer=cont.customer
            if cont.opportunity:
                opp = cont.opportunity
            else:
                opp = None
        else: 
            #action is called in Customer context
            customer = obj
            opp = None
        
        email_actions = lemonade.model.EmailAction.query.filter_by(show_in_customer_context=True).all()
        if len(email_actions)>0:
            #creat the actual sendmailactions here
            action_list=[]
            for email_action in email_actions:
                action=StandardEmailAction()
                action.customer = customer
                action.opportunity=opp
                action.email_action=email_action
                #fixme: problem wenn Icon None
                action.icon = os.path.abspath(os.path.join(settings.CAMELOT_MEDIA_ROOT(),'icons', email_action.icon.name))
                print action.icon
                action.verbose_name=email_action.label
                action.tooltip=email_action.description
                action_list.append(action)
            
            #dialog
            chosenaction =  yield ContextActionDialog(action_list,  title = _("Send standard email..."))
            
            if chosenaction:
                yield chosenaction
            

class StandardEmailAction(Action):
    def model_run(self,  model_context):
        #get the url
        url = self.email_action.get_mailto_url(self.customer)
        print url
        QDesktopServices.openUrl(url)
            
            #contact entry?
        if self.email_action.create_contact_entry:
            contact = self.email_action.make_contact_entry(self.customer)
            if self.opportunity:
                contact.opportunity=self.opportunity
            contact_admin=model_context.admin.get_related_admin(lemonade.model.Contact)
            yield OpenFormView([contact],  contact_admin)
        
class ContactFromEmail(Action):
    verbose_name='Contact entry from email'
    drop_mime_types = ['text/html','text/plain', 'message/html' 'message/rfc822']
    
    def model_run(self,  event):
        print event.mimeData().hasUrls()
        print "Triggered"
        print model_context.get_object()


class ConvertVoucher(Action):
    '''Converts a voucher to one of the VoucherTypes that are allowed'''
    verbose_name="Convert voucher"

    def model_run( self, model_context ):
        from lemonade.model import Voucher
        voucher = model_context.get_object()
        if voucher:
            #check if Voucher has been saved to database first!
            if model_context.admin.get_related_admin(Voucher).is_persistent(voucher) and not voucher.canceled:
                possible_types = voucher.voucher_type.successor_voucher_types
                if len(possible_types) > 0:
                    actionslist=[]
                    for vt in possible_types:
                        iconpath = os.path.join(settings.CAMELOT_MEDIA_ROOT(),'icons',  vt.icon.name)
                        convert_action = ConvertVoucherTo(vt.name, iconfile = iconpath)
                        actionslist.append(convert_action)
                    #actionslist.append(PrintVoucher) ##This way we can also insert single additional actions
                    
                    chosenaction =  yield ContextActionDialog(actionslist,  title = _("Convert voucher to..."))
                    
                    if chosenaction:
                        #get all vouchers for the vouchers transaction
                        transaction_vouchers = Voucher.query.filter_by(transaction=voucher.transaction).all()
                        same_type_transaction_vouchers =[v for v in transaction_vouchers if v.voucher_type.name == chosenaction.voucher_type_name and v !=voucher]
                        number_of_same_vouchers = len(same_type_transaction_vouchers)
                        if number_of_same_vouchers > 0:
                            answer = yield MessageBox( _('At least %i other voucher(s) of this type exists in the same transaction. Do you still want to create a voucher of this type?' %number_of_same_vouchers),  icon=QMessageBox.Information,  standard_buttons=QMessageBox.Ok|QMessageBox.Cancel)
                            if answer == QMessageBox.Ok:
                                yield chosenaction
                        else:
                            yield chosenaction
                else:
                    yield MessageBox( _('This voucher can not be converted' ),  icon=QMessageBox.Information,  standard_buttons=QMessageBox.Ok)
            else:
                 yield MessageBox( _('This voucher can not be converted' ),  icon=QMessageBox.Information,  standard_buttons=QMessageBox.Ok)


class ConvertVoucherTo( Action ):
    verbose_name = _('Convert voucher')
    tooltip = _('Convert (copy) this voucher to a successing voucher type')
    
    def __init__(self,  voucher_type_name, iconfile=None):
        super(ConvertVoucherTo,  self).__init__()
        self.voucher_type_name = voucher_type_name
        self.verbose_name = _('%s' %voucher_type_name)
        self.icon =iconfile
        self.tooltip=_('Convert voucher to %s' %voucher_type_name)
    
    def model_run( self, model_context ):
        from camelot.view.action_steps import (OpenFormView, Refresh, CloseView,  )
        from lemonade.model import Voucher,  VoucherType
        import datetime
        session = Session()
        voucher = model_context.get_object()

        new_voucher_type = VoucherType.query.filter_by(name= self.voucher_type_name).first()
        #copy the voucher object
        newvoucher=model_context.admin.copy(voucher, Voucher())
        newvoucher._voucher_type=new_voucher_type
        newvoucher.voucher_date=datetime.date.today()
        newvoucher.printed=False
        newvoucher.canceled=False
        newvoucher._payment_term=voucher.payment_term
        newvoucher.transaction = voucher.transaction
        
        session.flush()
        newvoucher_admin=model_context.admin.get_related_admin(Voucher)
        yield OpenFormView([newvoucher],  newvoucher_admin)
        yield CloseView()
        yield Refresh()
        
        

class SendDocumentByEmail(Action):
    verbose_name=_('Send Document by Email')
    icon = Icon('tango/32x32/actions/document-print.png')
    tooltip = _('Send the currently selected Document by email')
    
    def model_run( self, model_context ):
        document = model_context.get_object()
        if document:
            file = document.file.name
            att_name = os.path.abspath(os.path.join(settings.CAMELOT_MEDIA_ROOT(),'documents', document.file.name))
            url = QUrl(u'mailto:%s?subject=%s&body=\n\n\nAttachment: %s&Attachment=%s' %( '', document.document_name, file, att_name))
            print url
            QDesktopServices.openUrl(url)
    

class PrintVoucher( Action):
    verbose_name = _('Print voucher')
    icon = Icon('tango/32x32/actions/document-print.png')
    tooltip = _('Print the currently selected voucher')

    def model_run( self, model_context ):
        from lemonade.model import Voucher
        voucher = model_context.get_object()
        if voucher and model_context.admin.get_related_admin(Voucher).is_persistent(voucher):
            
            template = voucher.print_template()
            if os.path.exists(template):
                    
                #where are the templates?
                fileloader = FileSystemLoader(resource_filename(lemonade.__name__, 'templates'))
                e = Environment(loader=fileloader)
                
                preferences = lemonade.model.Preferences.get_preferrences()
                
                context=dict(
                             
                             #additional CSS
                             style = '', 
                             
                             ##voucher variables
                             #related entities
                            voucher_positions = voucher.voucher_positions, 
                            voucher_type_name = voucher.get_voucher_type_name(), 
                            customer = voucher.customer, 
                            currency = voucher.currency, 
                            payment_term =voucher.payment_term, 
                            transaction_id=voucher.transaction, 
                            #properties
                            voucher_number = voucher.voucher_number, 
                            voucher_date = voucher.voucher_date, 
                            delivery_date  = voucher.delivery_date, 
                            due_date  = voucher.due_date, 
                            paid_date =voucher.paid_date, 
                            canceled= voucher.canceled, 
                            printed=voucher.printed, 
                            customer_number = voucher.customer_number, 
                            customer_reference = voucher.customer_reference, 
                            company_name = voucher.company_name, 
                            company_additional = voucher.company_additional, 
                            person_salutation = voucher.person_salutation, 
                            person_letter_salutation = voucher.person_letter_salutation, 
                            person_firstname = voucher.person_firstname, 
                            person_lastname = voucher.person_lastname, 
                            additional_address_info = voucher.additional_address_info, 
                            street_box = voucher.street_box, 
                            address_zip = voucher.address_zip, 
                            address_city = voucher.address_city, 
                            address_country = voucher.address_country, 
                            vat_id = voucher.vat_id, 
                            supplyer_id = voucher.supplyer_id, 
                            payment_term_text = voucher.payment_term_text, 
                            payment_term_days =voucher.payment_term_days, 
                            pre_text = voucher.pre_text, 
                            post_text = voucher.post_text, 
                            net_total = voucher.net_total, 
                            total_tax = voucher.total_tax, 
                            total_tax_values = voucher.total_tax_values,  #dict
                            total = voucher.total, 
                            total_weight = voucher.total_weight, 
                            shipping_method = voucher.shipping_method, 
                            
                            own_logo=unicode(QUrl.fromLocalFile(os.path.abspath(os.path.join(settings.CAMELOT_MEDIA_ROOT(),'logo',  preferences.logo.name))).toString()), 
                            own_company_name = preferences.company_name, 
                            own_company_additional = preferences.company_additional,
                            own_address1 = preferences.company_address1, 
                            own_address2 = preferences.company_address2, 
                            own_zip = preferences.company_zip,  
                            own_citiy = preferences.company_city, 
                            own_country = preferences.company_country, 
                            own_email = preferences.company_email, 
                            own_website = preferences.company_website, 
                            own_vat_id = preferences.company_vat_id, 
                            own_bank = preferences.company_bank, 
                            own_BIC = preferences.company_BIC, 
                            own_IBAN = preferences.company_IBAN, 
                            own_legal_form = preferences.company_legal_form, 
                            own_phone = preferences.company_phone, 
                            own_fax = preferences.company_fax, 
                            own_legal_info1=preferences.company_legal_info1, 
                            own_legal_info2=preferences.company_legal_info2, 
                            own_legal_info3 = preferences.company_legal_info3, 
                             )
                t = e.get_template('voucher.html')
        
                html = t.render(context)
                session = Session()
                voucher.printed = True
        
                yield WebKitPrintPreview( html )
                yield FlushSession(session)
            else:
                yield MessageBox( _('No valid print template for this voucher available. Please select one in the Voucher Type Preferences'),  icon=QMessageBox.Warning,  standard_buttons=QMessageBox.Ok)
        else:
            yield MessageBox( _('This voucher can not be printed. Is it complete, yet!'),  icon=QMessageBox.Information,  standard_buttons=QMessageBox.Ok)



class SendEmail( Action ):

    verbose_name = _('Send Email')
    icon = Icon('tango/32x32/actions/mail-message-new.png')
    tooltip = _('Send Email to Customer and create a new contact entry')

    def model_run( self, model_context ):
        from camelot.view.action_steps import (OpenFormView, Refresh, MessageBox)
        import datetime
        from lemonade.model import Contact
        obj = model_context.get_object()
        if type(obj) == lemonade.model.Opportunity:
            #action is called in Opportunity context
            opp = obj
            customer = opp.customer
        elif type(obj) == lemonade.model.Contact:
            #action is called in Contact context
            cont = obj
            customer=cont.customer
            if cont.opportunity:
                opp = cont.opportunity
            else:
                opp = None
        else: 
            #action is called in Customer context
            customer = obj
            opp = None
            
        #TODO: just proof of concept here connect to actual data and include templating for standard texts
        if customer.prefered_email:
#            url = QUrl(u'mailto:%s?subject=%s&body=%s' %( customer.prefered_email.mechanism[1], 'Betreff', 'Guten Tag %s %s, \n' %(customer.person_salutation, customer.person_lastname)))
            url = QUrl(u'mailto:%s?subject=%s&body=%s&Attachment=/home/sebste/Python/Lemonade/mercurial/lemonade-business-suite/src/splash.png' %( customer.prefered_email.mechanism[1], 'Betreff', 'Guten Tag %s %s, \n' %(customer.person_salutation, customer.person_lastname)))
            QDesktopServices.openUrl(url)
            #do contact entry?
            yield MessageBox(_(u'do you want to create a contract history entry for this email?'), icon=4, title=_('Create contact history entry?'))
            
            session=Session()
            contact = Contact()
            myuser = lemonade.model.User.query.filter_by(username=getpass.getuser()).first()
            if myuser:
                contact.user=myuser
            contact.customer=customer
            contact.datetime=datetime.datetime.now()
            contact.type='email'
            contact.direction='out'
            contact.summary=u'sent email...'
            if opp:
                contact.opportunity=opp
            session.flush()
            #open object in FormView
            contact_admin = model_context.admin.get_related_admin(Contact)
            yield OpenFormView([contact], contact_admin)
            #refresh Gui
            yield Refresh()

    

class SendStandardEmail1( Action ):
    verbose_name = _('Send Standard Email1')
    #icon = Icon('tango/16x16/actions/document-print.png')
    tooltip = _('Convert (copy) this voucher to a successing voucher type')
    
    def model_run( self, model_context ):
        yield PrintHtml( 'Send Standard Email1' )
    pass
    
class SendStandardEmail2( Action ):
    verbose_name = _('Send Standard Email2')
    #icon = Icon('tango/16x16/actions/document-print.png')
    tooltip = _('Convert (copy) this voucher to a successing voucher type')
    
    def model_run( self, model_context ):
        yield PrintHtml( 'Send Standard Email2' )
    pass

class SendStandardEmail3( Action ):
    verbose_name = _('Send Standard Email3')
    #icon = Icon('tango/16x16/actions/document-print.png')
    tooltip = _('Convert (copy) this voucher to a successing voucher type')
    
    def model_run( self, model_context ):
        yield PrintHtml( 'Send Standard Email3' )
    pass
    
    
class SendInfoPackage( Action ):
    verbose_name = _('InfoPackage')
    icon = Icon('tango/32x32/apps/internet-email.png')
    tooltip = _('Convert (copy) this voucher to a successing voucher type')
    
    def model_run( self, model_context ):
        
        yield PrintHtml( 'InfoPackage' )
    pass

    
class SendLetter( Action ):

    verbose_name = _('Send Letter')
    icon = Icon('tango/32x32/apps/internet-mail.png')
    tooltip = _('Convert (copy) this voucher to a successing voucher type')
    
    def model_run( self, model_context ):
        yield PrintHtml( 'Send Letter' )
    pass



class CallPreferedPhone( Action ):
    verbose_name = _('Call Prefered Phone')
    #icon = Icon('tango/16x16/actions/document-print.png')
    #icon='/icons/oxygen/128x128/apps/internet-telephony.png'
    tooltip = _('call the customers phone number that is marked as prefered')
    
    def model_run( self, model_context ):
        from camelot.view.action_steps import (OpenFormView, Refresh)
        import datetime
        from lemonade.model import Contact
        
        obj = model_context.get_object()
        if type(obj) == lemonade.model.Opportunity:
            #action is called in Opportunity context
            opp = obj
            customer = opp.customer
        elif type(obj) == lemonade.model.Contact:
            #action is called in Contact context
            cont = obj
            customer=cont.customer
            if cont.opportunity:
                opp = cont.opportunity
            else:
                opp = None
        else: 
            #action is called in Customer context
            customer = obj
            opp = None
        
        name = customer.person_firstname + " " +customer.person_lastname
        
        if customer.prefered_phone :
            number = unicode(customer.prefered_phone.mechanism[1])
            number = number.replace(' ', '')
            #yield MessageBox( 'Calling %s %s on number ... %s' % (customer.person_firstname, customer.person_lastname,  number) icon=QMessageBox.Information)
            
            preferences = lemonade.model.Preferences.get_preferrences()
            
            if preferences.telephony_system == "Command Line Interface":
                user =preferences.telephony_default_user
                password =preferences.telephony_default_password
                shellcommand = preferences.telephony_system_call_string
                shellcommand = shellcommand.replace('#user', user)
                shellcommand = shellcommand.replace('#password', password)
                shellcommand = shellcommand.replace('#number', str(number))
                result = os.system(shellcommand)
                #yield MessageBox( shellcommand+"\n Status:"+unicode(result ))
            else:
                url = "http://%s:%i"%(preferences.android_device_ip,  preferences.android_device_port)
                import socket
                socket.setdefaulttimeout(preferences.android_device_timeout) 
                import xmlrpclib
                try:
                    server = xmlrpclib.ServerProxy(url)
                    if preferences.android_use_call:
                        result = server.call_number(preferences.android_device_secret, number,  name)
                    else:
                        result = server.dial_number(preferences.android_device_secret, number,  name)
                    if not result[0]==0:
                        yield MessageBox( result[1],  icon=2, title=_('Lemonade Android Connector'))
                    
                except Exception, e:
                    yield MessageBox( 'Can not find %s in network. %s' % (url, e), icon=2,  title=_('Lemonade Android Connector'))

            yield MessageBox(_(u'Do you want to create a contract history entry for this call?'), icon=4, title=_('Create contact history entry?'))
        
            session=Session()
            contact = Contact()
            myuser = lemonade.model.User.query.filter_by(username=getpass.getuser()).first()
            if myuser:
                contact.user=myuser
            contact.customer=customer
            contact.datetime=datetime.datetime.now()
            contact.type='call'
            contact.direction='out'
            contact.summary=u'call out'
            if opp:
                contact.opportunity=opp
            session.flush()
            #open object in FormView
            contact_admin = model_context.admin.get_related_admin(Contact)
            yield OpenFormView([contact], contact_admin)
            #refresh Gui
            yield Refresh()


class OpenSettingsView(Action):
    verbose_name=('Preferences')
    icon = Icon('tango/22x22/categories/applications-system.png')
    tooltip = _('Application and Company settings')
    
    def model_run(self, model_context):
        from camelot.view.action_steps import OpenFormView, Refresh
        from lemonade.model import Preferences
        session=Session()
        preferences = Preferences.query.filter_by(id=1).first()
        preferrences_admin=model_context.admin.get_related_admin(Preferences)
        yield OpenFormView([preferences],  preferrences_admin)
        session.flush()
        yield Refresh()
